﻿using RemoteSensingImageDirectServer.Untils.Pool;

namespace RemoteSensingImageDirectServer.Untils.ScopeSpace
{
    public static class RasterEnvelopeFactory
    {
        /// <summary>
        /// 正常坐标系下根据xyz获取瓦片范围
        /// </summary>
        /// <param name="x">列</param>
        /// <param name="y">行</param>
        /// <param name="z">层级</param>
        /// <param name="tileSize">瓦片大小</param>
        /// <param name="epsg">使用坐标系的epsg编码</param>
        /// <returns>返回一个有效的坐标系范围</returns>
        public static RasterEnvelope CreateREnvelopeFromXYZ(int x, int y, int z, int tileSize, int epsg)
        {
            if (epsg == 4326 || epsg == 4490)
            {
                double resolution = TileResTierPool.Instance().Wgs84Levels[z - 1];//获取此等级下的分辨率
                double imageSize = resolution * tileSize;//根据分辨率及瓦片大小，确定图片范围大小
                double left = (double)x * imageSize + TileResTierPool.Instance().EnvWGS84.MinX; //以左上角为原点计算瓦片左边的绝对位置
                double top = TileResTierPool.Instance().EnvWGS84.MaxY - (double)y * imageSize; //以左上角为原点计算瓦片上边的绝对位置
                double right = (double)(x + 1) * imageSize + TileResTierPool.Instance().EnvWGS84.MinX; //以左上角为原点计算瓦片右边的绝对位置
                double bottom = TileResTierPool.Instance().EnvWGS84.MaxY - (double)(y + 1) * imageSize; //以左上角为原点计算瓦片下边的绝对位置
                return new RasterEnvelope(left, bottom, right, top, resolution, -resolution);
            }
            else
            {
                double resolution = TileResTierPool.Instance().MercatorLevels[z];//获取此等级下的分辨率
                double imageSize = resolution * tileSize;
                double left = (double)x * imageSize + TileResTierPool.Instance().EnvWebMercator.MinX;
                double top = TileResTierPool.Instance().EnvWebMercator.MaxY - (double)y * imageSize;
                double right = (double)(x + 1) * imageSize + TileResTierPool.Instance().EnvWebMercator.MinX;
                double bottom = TileResTierPool.Instance().EnvWebMercator.MaxY - (double)(y + 1) * imageSize;
                return new RasterEnvelope(left, bottom, right, top, resolution, -resolution);
            }
        }

        /// <summary>
        /// 特殊坐标系下根据xyz获取瓦片范围
        /// </summary>
        /// <param name="x">列</param>
        /// <param name="y">行</param>
        /// <param name="z">层级</param>
        /// <param name="tileSize">瓦片大小</param>
        /// <param name="env">特殊坐标系的有效范围</param>
        /// <returns>返回一个有效的坐标系范围</returns>
        public static RasterEnvelope CreateREnvelopeFromSpecialXYZ(int x, int y, int z, int tileSize, RasterEnvelope env)
        {
            double resolution = TileResTierPool.Instance().MercatorLevels[z];//获取此等级下的分辨率
            double imageSize = resolution * tileSize;
            double left = (double)x * imageSize + env.MinX;
            double top = env.MaxY - (double)y * imageSize;
            double right = (double)(x + 1) * imageSize + env.MinX;
            double bottom = env.MaxY - (double)(y + 1) * imageSize;
            return new RasterEnvelope(left, bottom, right, top, resolution, -resolution);
        }

        /// <summary>
        /// 超图特殊坐标系下根据xyz获取瓦片范围
        /// </summary>
        /// <param name="x">列</param>
        /// <param name="y">行</param>
        /// <param name="z">层级</param>
        /// <param name="tileSize">瓦片大小</param>
        /// <param name="env">超图特殊坐标系的有效范围</param>
        /// <returns>返回一个有效的坐标系范围</returns>
        public static RasterEnvelope CreateREnvelopeFromSuperMapXYZ(int x, int y, int z, int tileSize, RasterEnvelope env)
        {
            double resolution = TileResTierPool.Instance().SuperMapLevels[z];//获取此等级下的分辨率
            double imageSize = resolution * tileSize;
            double left = (double)x * imageSize + env.MinX;
            double top = env.MaxY - (double)y * imageSize;
            double right = (double)(x + 1) * imageSize + env.MinX;
            double bottom = env.MaxY - (double)(y + 1) * imageSize;
            return new RasterEnvelope(left, bottom, right, top, resolution, -resolution);
        }
    }
}
